home *** CD-ROM | disk | FTP | other *** search
/ Developer CD Series 1997 February: Technology Seed / Mac Tech Seed Feb '97.toast / ODF Release 3 / ODFDev / Draw / Sources / Content.cpp < prev    next >
Encoding:
Text File  |  1996-12-16  |  22.7 KB  |  817 lines  |  [TEXT/MPS ]

  1. //========================================================================================
  2. //
  3. //    File:                Content.cpp
  4. //    Release Version:    $ ODF 3 $
  5. //
  6. //    Copyright:    (c) 1993 - 1996 by Apple Computer, Inc., all rights reserved.
  7. //
  8. //========================================================================================
  9.  
  10. #include "ODFDraw.hpp"
  11.  
  12. #ifndef CONTENT_H
  13. #include "Content.h"
  14. #endif
  15.  
  16. #ifndef DRAWPART_H
  17. #include "DrawPart.h"
  18. #endif
  19.  
  20. #ifndef DRAWCLIP_H
  21. #include "DrawClip.h"
  22. #endif
  23.  
  24. #ifndef BASESHP_H
  25. #include "BaseShp.h"
  26. #endif
  27.  
  28. #ifndef GROUPSHP_H
  29. #include "GroupShp.h"
  30. #endif
  31.  
  32. #ifndef DRAWPRXY_H
  33. #include "DrawPrxy.h"
  34. #endif
  35.  
  36. #ifndef UTILS_H
  37. #include "Utils.h"
  38. #endif
  39.  
  40. #ifndef DRAWLINK_H
  41. #include "DrawLink.h"
  42. #endif
  43.  
  44. #ifndef DRWPRMSE_H
  45. #include "DrwPrmse.h"
  46. #endif
  47.  
  48. #ifndef DRAWSEL_H
  49. #include "DrawSel.h"
  50. #endif
  51.  
  52. // ----- Part Layer -----
  53.  
  54. #ifndef FWUTIL_H
  55. #include "FWUtil.h"
  56. #endif
  57.  
  58. #ifndef FWPRESEN_H
  59. #include "FWPresen.h"
  60. #endif
  61.  
  62. #ifndef FWKIND_H
  63. #include "FWKind.h"
  64. #endif
  65.  
  66. // ----- OS Layer -----
  67.  
  68. #ifndef FWSUUTIL_H
  69. #include "FWSUUtil.h"
  70. #endif
  71.  
  72. #ifndef FWRECT_H
  73. #include "FWRect.h"
  74. #endif
  75.  
  76. #ifndef FWODGEOM_H
  77. #include "FWODGeom.h"
  78. #endif
  79.  
  80. #ifndef FWSUSINK_H
  81. #include "FWSUSink.h"
  82. #endif
  83.  
  84. #ifndef FWBARRAY_H
  85. #include "FWBArray.h"
  86. #endif
  87.  
  88. #ifndef FWFILEAC_H
  89. #include "FWFileAc.h"
  90. #endif
  91.  
  92. #ifndef SLMixOS_H
  93. #include "SLMixOS.h"
  94. #endif
  95.  
  96. #ifndef FWPICTUR_H
  97. #include "FWPictur.h"
  98. #endif
  99.  
  100. // ----- Foundation Layer -----
  101.  
  102. #ifndef FWSTREAM_H
  103. #include "FWStream.h"
  104. #endif
  105.  
  106. #ifndef FWSUSINK_H
  107. #include "FWSUSink.h"
  108. #endif
  109.  
  110. #ifndef FWMEMORY_H
  111. #include "FWMemory.h"
  112. #endif
  113.  
  114. // ----- OpenDoc Includes -----
  115.  
  116. #ifndef SOM_Module_OpenDoc_StdProps_defined
  117. #include <StdProps.xh>
  118. #endif
  119.  
  120. #ifndef SOM_ODTranslation_xh
  121. #include <Translt.xh>
  122. #endif
  123.  
  124. #ifndef SOM_ODShape_xh
  125. #include <Shape.xh>
  126. #endif
  127.  
  128. #ifndef SOM_ODStorageUnit_xh
  129. #include <StorageU.xh>
  130. #endif
  131.  
  132. #ifndef SOM_ODSession_xh
  133. #include <ODSessn.xh>
  134. #endif
  135.  
  136. #ifdef __MRC__
  137. // This is to go around a bug in MRC. It doesn't seems to see the extern
  138. // in BaseShp.cpp
  139. FW_DEFINE_AUTO_TEMPLATE(FW_TRefCountedCollection, CBaseShape)
  140. #endif
  141.  
  142. //========================================================================================
  143. //    Segmentation
  144. //========================================================================================
  145.  
  146. #ifdef FW_BUILD_MAC
  147. #pragma segment odfdraw2
  148. #endif
  149.  
  150. //========================================================================================
  151. //    class CDrawContent
  152. //========================================================================================
  153.  
  154. FW_DEFINE_AUTO(CDrawContent)
  155.  
  156. //----------------------------------------------------------------------------------------
  157. //    CDrawContent::CDrawContent
  158. //----------------------------------------------------------------------------------------
  159. //    CDrawContent constructor
  160.  
  161. CDrawContent::CDrawContent(Environment* ev, CDrawPart* part, const FW_CRect& contentRect) :
  162.     FW_CContent(ev, part),
  163.     fShapeList(NULL),
  164.     fDrawPart(part),
  165.     fProxyShapeCount(0),
  166.     fContentRect(contentRect)
  167. {
  168.     fShapeList = FW_NEW(CShapeCollection, ());
  169.     
  170.     FW_END_CONSTRUCTOR
  171. }
  172.  
  173. //----------------------------------------------------------------------------------------
  174. //    CDrawContent::CDrawContent
  175. //----------------------------------------------------------------------------------------
  176.  
  177. CDrawContent::CDrawContent(Environment* ev, CDrawPart* part, CDrawContent* other) :
  178.     FW_CContent(ev, part),
  179.     fShapeList(NULL),
  180.     fDrawPart(part),
  181.     fProxyShapeCount(0),
  182.     fContentRect(FW_kZeroRect)
  183. {
  184.     fShapeList = FW_NEW(CShapeCollection, ());
  185.  
  186.     if (other != NULL)
  187.     {
  188.         fContentRect = other->fContentRect;
  189.         
  190.         CDrawContentShapeIterator ite(other);
  191.         for (CBaseShape* shape = ite.First(); ite.IsNotComplete(); shape = ite.Next())
  192.         {
  193.             this->AddShape(ev, shape);
  194.         }
  195.     }
  196.     
  197.     FW_END_CONSTRUCTOR
  198. }
  199.  
  200. //----------------------------------------------------------------------------------------
  201. //    CDrawContent::~CDrawContent
  202. //----------------------------------------------------------------------------------------
  203. //    CDrawContent destructor
  204.  
  205. CDrawContent::~CDrawContent()
  206. {
  207.     FW_START_DESTRUCTOR
  208.     delete fShapeList;
  209. }
  210.  
  211. //----------------------------------------------------------------------------------------
  212. //    CDrawContent::AddShape
  213. //----------------------------------------------------------------------------------------
  214.  
  215. void CDrawContent::AddShape(Environment* ev, CBaseShape* shape, CBaseShape* nextShape)
  216. {
  217.     if (fShapeList->Contains(shape)) return;    // don't add shape twice
  218.  
  219.     if (nextShape == NULL)
  220.         fShapeList->AddLast(shape);
  221.     else
  222.         fShapeList->AddBefore(nextShape, shape);
  223.  
  224.     if (shape->GetShapeType() == kProxyShape)
  225.     {
  226.         fProxyShapeCount++;
  227.     }
  228.     else if (shape->GetShapeType() == kGroupShape)    // thanks, Troy!
  229.     {
  230.         fProxyShapeCount += ((CGroupShape*) shape)->CountProxyShapes(ev);
  231.     }
  232. }
  233.  
  234. //----------------------------------------------------------------------------------------
  235. //    CDrawContent::RemoveShape
  236. //----------------------------------------------------------------------------------------
  237.  
  238. void CDrawContent::RemoveShape(Environment* ev, CBaseShape* shape)
  239. {
  240.     FW_ASSERT(fShapeList->Contains(shape));
  241.  
  242.     if (shape->GetShapeType() == kProxyShape)
  243.     {
  244.         fProxyShapeCount--;
  245.     }
  246.     else if (shape->GetShapeType() == kGroupShape)
  247.     {
  248.         fProxyShapeCount -= ((CGroupShape*) shape)->CountProxyShapes(ev);
  249.             // ••• Ultimately, this might not be quite right.  
  250.             //     If a proxy is removed from the group before the group is 
  251.             //       removed from the content, the count here could be wrong.
  252.     }
  253.  
  254.     fShapeList->RemoveAndRelease(shape);
  255.  
  256. }
  257.  
  258. //----------------------------------------------------------------------------------------
  259. //    CDrawContent::RemoveShapeFromContent
  260. //----------------------------------------------------------------------------------------
  261.  
  262. void CDrawContent::RemoveShapeFromContent(Environment* ev, CBaseShape* shape)
  263. {
  264.     RemoveShape(ev, shape);
  265.     shape->Removed(ev);  // notify shape
  266. }
  267.  
  268. //----------------------------------------------------------------------------------------
  269. //    CDrawContent::Count
  270. //----------------------------------------------------------------------------------------
  271.  
  272. unsigned long CDrawContent::CountShapes() const
  273. {
  274.     return fShapeList->Count();
  275. }
  276.  
  277. //----------------------------------------------------------------------------------------
  278. //    CDrawContent::Count
  279. //----------------------------------------------------------------------------------------
  280.  
  281. void CDrawContent::EmptyShapes(Environment* ev)
  282. {
  283. FW_UNUSED(ev);
  284.     if (fShapeList)
  285.     {
  286.         fShapeList->RemoveAndReleaseAll();
  287.         fProxyShapeCount = 0;
  288.     }
  289. }
  290.  
  291. //----------------------------------------------------------------------------------------
  292. //    CDrawContent::GetFirstShape
  293. //----------------------------------------------------------------------------------------
  294.  
  295. CBaseShape* CDrawContent::GetFirstShape() const
  296. {
  297.     return fShapeList->First();
  298. }
  299.  
  300. //----------------------------------------------------------------------------------------
  301. //    CDrawContent::GetShapeAfter
  302. //----------------------------------------------------------------------------------------
  303. CBaseShape* CDrawContent::GetShapeAfter(CBaseShape* shape) const
  304. {
  305.     return fShapeList->After(shape);
  306. }
  307.  
  308. //----------------------------------------------------------------------------------------
  309. //    CDrawContent::IsEmpty
  310. //----------------------------------------------------------------------------------------
  311.  
  312. FW_Boolean CDrawContent::IsEmpty() const
  313. {
  314.     return (fShapeList->Count() == 0);
  315. }
  316.  
  317. //----------------------------------------------------------------------------------------
  318. //    CDrawContent::CalcUpdateShape
  319. //----------------------------------------------------------------------------------------
  320.  
  321. ODShape* CDrawContent::CalcUpdateShape(Environment* ev)
  322. {
  323.     if (this->IsEmpty())
  324.         return NULL;
  325.  
  326.     ODShape* updateShape = ::FW_NewODShape(ev);
  327.  
  328.     FW_CAcquiredODShape aqTempShape = ::FW_NewODShape(ev);
  329.     FW_Boolean first = TRUE;
  330.  
  331.     CDrawContentShapeIterator ite(this);
  332.     for (CBaseShape* shape = ite.First(); ite.IsNotComplete(); shape = ite.Next())
  333.     {
  334.         shape->GetUpdateBox(ev, aqTempShape);
  335.         if (first)
  336.             updateShape->CopyFrom(ev, aqTempShape);
  337.         else
  338.             updateShape->Union(ev, aqTempShape);
  339.                         
  340.         first = FALSE;
  341.     }
  342.  
  343.     return updateShape;
  344. }
  345.  
  346. //----------------------------------------------------------------------------------------
  347. //    CDrawContent::RedrawShapes
  348. //----------------------------------------------------------------------------------------
  349.  
  350. void CDrawContent::RedrawShapes(Environment* ev)
  351. {
  352.     // Calculate the update shape and invalidate it
  353.     FW_CAcquiredODShape updateShape = CalcUpdateShape(ev);
  354.     if (updateShape != NULL) 
  355.         this->RedrawShape(ev, updateShape);
  356. }
  357.  
  358. //----------------------------------------------------------------------------------------
  359. //    CDrawContent::RedrawShape
  360. //----------------------------------------------------------------------------------------
  361.  
  362. void CDrawContent::RedrawShape(Environment* ev, CBaseShape* shape)
  363. {
  364.     FW_CAcquiredODShape updateShape = ::FW_NewODShape(ev);
  365.     
  366.     shape->GetUpdateBox(ev, updateShape);
  367.     this->RedrawShape(ev, updateShape);
  368. }
  369.  
  370. //----------------------------------------------------------------------------------------
  371. //    CDrawContent::RedrawShape
  372. //----------------------------------------------------------------------------------------
  373.  
  374. void CDrawContent::RedrawShape(Environment* ev, ODShape* odShape)
  375. {
  376.     FW_CPresentation* presentation = fDrawPart->GetMainPresentation();
  377.     CDrawFacetClipper facetClipper(fDrawPart);
  378.     facetClipper.Clip(ev, presentation, odShape);
  379.     presentation->Invalidate(ev, odShape);
  380. }
  381.  
  382. //----------------------------------------------------------------------------------------
  383. //    CDrawContent::OffsetShapes
  384. //----------------------------------------------------------------------------------------
  385.  
  386. void CDrawContent::OffsetShapes(Environment* ev, const FW_CPoint& offset)
  387. {
  388.     CShapeCollectionIterator it(fShapeList);
  389.     for (CBaseShape* shape = it.First(); it.IsNotComplete(); shape = it.Next())
  390.     {
  391.         shape->OffsetShape(ev, offset.x, offset.y);
  392.     }
  393. }
  394.  
  395. //----------------------------------------------------------------------------------------
  396. //    CDrawContent::IsOKtoWrite
  397. //----------------------------------------------------------------------------------------
  398.  
  399. FW_Boolean CDrawContent::IsOKtoWrite(Environment* ev, CBaseShape* shape)
  400. {
  401. FW_UNUSED(ev);
  402. FW_UNUSED(shape);
  403.     return TRUE;    // the default
  404. }
  405.  
  406. //----------------------------------------------------------------------------------------
  407. //    CDrawContent::PostInternalizeShape
  408. //----------------------------------------------------------------------------------------
  409.  
  410. void CDrawContent::PostInternalizeShape(Environment* ev, 
  411.                                         const FW_CPoint& offset, 
  412.                                         CBaseShape* shape, 
  413.                                         short i)
  414. {
  415. FW_UNUSED(ev);
  416. FW_UNUSED(offset);
  417. FW_UNUSED(shape);
  418. FW_UNUSED(i);
  419.     // Default is to do nothing
  420. }
  421.  
  422. //----------------------------------------------------------------------------------------
  423. //    CDrawContent::ExternalizeShapeList
  424. //----------------------------------------------------------------------------------------
  425.  
  426. void CDrawContent::ExternalizeShapeList(Environment* ev,
  427.                                         ODStorageUnit* storageUnit, 
  428.                                         FW_CCloneInfo* cloneInfo,
  429.                                         FW_Fixed offsetX,
  430.                                         FW_Fixed offsetY)
  431. {
  432.     // ----- Create an archive for our shapes -----
  433.     FW_PStorageUnitSink suSink(ev, storageUnit, kODPropContents, fDrawPart->GetPartKind(ev)->GetType(ev));
  434.     CDrawWritableStream archive(ev, suSink, suSink, cloneInfo);
  435.     
  436.     // ----- Write number of shapes -----
  437.     unsigned long count = fShapeList->Count();
  438.     archive << count;
  439.     
  440.     // ----- Write top, left offsets -----
  441.     archive << offsetX;
  442.     archive << offsetY;
  443.  
  444.     // ----- Write shapes -----
  445.     short extIndex = 1;    // externalization index, used by links to identify shapes
  446.     CShapeCollectionIterator ite(fShapeList);
  447.     for (CBaseShape* theShape = ite.First(); ite.IsNotComplete(); theShape = ite.Next())
  448.     {
  449.         if (this->IsOKtoWrite(ev, theShape))
  450.         {
  451.             FW_WRITE_DYNAMIC_OBJECT(archive, theShape, CBaseShape);
  452.             theShape->SetExternalizationIndex(extIndex++);    // so links can write their shapes' indices
  453.         }
  454.     }    
  455.     
  456.     FW_SUDeleteEndOfFocusedValue(ev, storageUnit);
  457. }
  458.  
  459. //----------------------------------------------------------------------------------------
  460. //    CDrawContent::InternalizeShapeList
  461. //----------------------------------------------------------------------------------------
  462.  
  463. void CDrawContent::InternalizeShapeList(Environment* ev,
  464.                                         ODStorageUnit* storageUnit, 
  465.                                         FW_CCloneInfo* cloneInfo)
  466. {
  467.     // ----- Create an Archive for our shapes -----
  468.     FW_PStorageUnitSink suSink(ev, storageUnit, kODPropContents, fDrawPart->GetPartKind(ev)->GetType(ev));
  469.     FW_PBufferedSink sink(ev, suSink);
  470.     CDrawReadableStream archive(ev, fDrawPart, sink, suSink, cloneInfo);
  471.     
  472.     // ----- Read number of shapes -----
  473.     unsigned long count;
  474.     archive >> count;
  475.  
  476.     // ----- Read top left offset -----
  477.     FW_CPoint offset;
  478.     archive >> offset.x;
  479.     archive >> offset.y;
  480.  
  481.     for (short i = 1; i<=count; i++)
  482.     {
  483.         CBaseShape* theShape = NULL;
  484.         FW_READ_DYNAMIC_OBJECT(archive, &theShape, CBaseShape);
  485.         FW_ASSERT(theShape);
  486.         
  487.         // ----- Add the shape to the shape list -----
  488.         this->AddShape(ev, theShape);
  489.  
  490.         // ----- Do whatever else needs to be done to the shape -----
  491.         this->PostInternalizeShape(ev, offset, theShape, i);
  492.         
  493.         theShape->Release();  // AddShape acquired it
  494.     }
  495. }
  496.  
  497. //----------------------------------------------------------------------------------------
  498. //    CDrawPartContent::ExternalizeKind
  499. //----------------------------------------------------------------------------------------
  500.  
  501. void CDrawContent::ExternalizeKind(Environment* ev,
  502.                                     ODStorageUnit* storageUnit, 
  503.                                     FW_CKind* kind,
  504.                                     FW_StorageKinds storageKind,
  505.                                     FW_CPromise* promise,
  506.                                     FW_CCloneInfo* cloneInfo)
  507. {
  508. FW_UNUSED(kind);
  509.  
  510.     if (promise)
  511.     {
  512.         promise->Promise(ev, storageUnit, kODPropContents, kind->GetType(ev));    // just promise
  513.     }
  514.     else if (kind->IsPartKind(ev))
  515.     {
  516.         ExternalizeShapeList(ev, storageUnit, cloneInfo, fContentRect.left, fContentRect.top);
  517.         
  518.         if (storageKind == FW_kPartStorage)
  519.         {
  520.             // ----- Write links -----
  521.             CDrawLinkManager* linkMgr = (CDrawLinkManager*) fDrawPart->GetLinkManager(ev);
  522.             linkMgr->ExternalizeLinks(ev, storageUnit, cloneInfo);
  523.         }
  524.     }
  525.     else if (kind->IsEqual(ev, 'PICT', kODPlatformDataType))
  526.     {
  527.         FW_CPicture picture;
  528.         
  529.         {
  530.             FW_CPictureContext pc(ev, picture, fContentRect.Width(), fContentRect.Height());
  531.             
  532.             // ----- Draw all the shapes -----
  533.             CDrawContentShapeIterator ite(this);
  534.             for (CBaseShape *shape = ite.First(); ite.IsNotComplete(); shape = ite.Next())
  535.             {
  536.                 if (shape->GetShapeType() != kProxyShape)
  537.                 {
  538.                     shape->OffsetShape(ev, -fContentRect.left, -fContentRect.top);
  539.                     shape->RenderShape(ev, NULL, pc);
  540.                     shape->OffsetShape(ev, fContentRect.left, fContentRect.top);
  541.                 }
  542.             }
  543.         }
  544.         
  545.         FW_PlatformPict platformPict = picture.GetPlatformPict();
  546.  
  547.         unsigned long pictSize = FW_CMemoryManager::GetSystemHandleSize((FW_PlatformHandle)platformPict);
  548.     
  549.         FW_CAcquireLockedSystemHandle lockedHandle((FW_PlatformHandle)platformPict);
  550.  
  551.         FW_PStorageUnitSink suSink(ev, storageUnit, kODPropContents, kind->GetType(ev));
  552.         FW_CWritableStream stream(suSink);
  553.         stream.Write(lockedHandle.GetPointer(), pictSize);
  554.     }
  555. #ifdef FW_DEBUG
  556.     else
  557.         FW_DEBUG_MESSAGE("CDrawPromiseContent::ExternalizeKind - unkown kind");
  558. #endif
  559. }
  560.  
  561. //----------------------------------------------------------------------------------------
  562. //    CDrawContent::InternalizeKind
  563. //----------------------------------------------------------------------------------------
  564.  
  565. FW_Boolean CDrawContent::InternalizeKind(Environment* ev,
  566.                                             ODStorageUnit* storageUnit, 
  567.                                             FW_CKind* kind,
  568.                                             FW_StorageKinds storageKind,
  569.                                             FW_CCloneInfo* cloneInfo)
  570. {    
  571.     if (kind->IsPartKind(ev))
  572.     {
  573.         // ----- [HLX] force promises to be fulfilled, otherwise bug in locks - OpenDoc Bug???
  574.         if (storageKind != FW_kPartStorage)
  575.         {
  576.             storageUnit->Focus(ev, kODPropContents, kODPosUndefined, kind->GetType(ev), 0, kODPosUndefined);
  577.             storageUnit->GetSize(ev);
  578.         }
  579.         
  580.         InternalizeShapeList(ev, storageUnit, cloneInfo);
  581.     
  582.         // ----- Read links -----
  583.         if (storageKind == FW_kPartStorage)
  584.         {
  585.             CDrawLinkManager* linkMgr = (CDrawLinkManager*)fDrawPart->GetLinkManager(ev);
  586.             linkMgr->InternalizeLinks(ev, storageUnit);
  587.         }
  588.     }
  589. #ifdef FW_DEBUG
  590.     else
  591.         FW_DEBUG_MESSAGE("CDrawPromiseContent::ExternalizeKind - unkown kind");
  592. #endif
  593.  
  594.     return true;
  595. }
  596.  
  597. //----------------------------------------------------------------------------------------
  598. //    CDrawContent::IsDataOnlyOneProxy
  599. //----------------------------------------------------------------------------------------
  600.  
  601. FW_MProxy* CDrawContent::IsDataOnlyOneProxy(Environment* ev) const
  602. {
  603. FW_UNUSED(ev);
  604.  
  605.     CBaseShape* shape = NULL;
  606.     
  607.     if (fProxyShapeCount == 1 && CountShapes() == 1)    
  608.     {
  609.         shape = GetFirstShape();
  610.         FW_ASSERT(shape != NULL);
  611.         
  612.         if (shape->GetShapeType() == kGroupShape)
  613.         {
  614.             // Test for the case where the only shape of the group is a proxy (link destination)
  615.             FW_ASSERT(FW_DYNAMIC_CAST(CGroupShape, shape));
  616.             if (((CGroupShape*)shape)->CountShapes() == 1)
  617.             {
  618.                 shape = ((CGroupShape*)shape)->GetFirstShape();
  619.                 FW_ASSERT(FW_DYNAMIC_CAST(CProxyShape, shape));
  620.             }
  621.             else
  622.                 shape = NULL;
  623.         }
  624.         else
  625.         {
  626.             FW_ASSERT(FW_DYNAMIC_CAST(CProxyShape, shape));
  627.         }
  628.     }
  629.     
  630.     return (CProxyShape*)shape;
  631. }
  632.  
  633. //----------------------------------------------------------------------------------------
  634. //    CDrawContent::AddSingleEmbeddedFrame
  635. //----------------------------------------------------------------------------------------
  636.  
  637. CProxyShape* CDrawContent::AddSingleEmbeddedFrame(Environment* ev, 
  638.                                                   FW_CEmbeddingFrame* scopeFrame,
  639.                                                   ODPart* embeddedPart, 
  640.                                                   ODFrame* embeddedFrame,
  641.                                                   ODShape* suggestedShape,
  642.                                                   ODTypeToken viewType)
  643. {
  644.     FW_ASSERT(((embeddedPart == NULL) && (embeddedFrame != NULL)) || ((embeddedPart != NULL) && (embeddedFrame == NULL)));
  645.     
  646.     // ----- Step 2: Calculate the default shape rect
  647.     FW_CRect shapeRect;
  648.     if (suggestedShape)
  649.     {
  650.         shapeRect = FW_GetShapeBoundingBox(ev, suggestedShape);
  651.         shapeRect.Offset(-shapeRect.left, -shapeRect.top);
  652.     }
  653.     else
  654.     {
  655.         shapeRect.SetInt(0, 0, 80, 80);
  656.     }
  657.  
  658.     // ----- Step 3: Calculate the shape of the embedded frame -----    
  659.     FW_CAcquiredODShape aqFrameShape = ::FW_NewODShape(ev, shapeRect);
  660.     
  661.     // ----- Step 4: Calculate its position -----
  662.     // ----- We are placing it in the middle of the content view -----
  663.     FW_CRect frameBounds = scopeFrame->GetContentView(ev)->GetBoundsInContent(ev);
  664.     shapeRect.PlaceInCenterOf(frameBounds);
  665.     
  666.     // ----- Step 5: Create the proxy shape -----
  667.     CProxyShape* proxyShape = FW_NEW(CProxyShape, (ev, shapeRect, fDrawPart));
  668.     // Make sure that if an exception occurs before we complete this method that
  669.     // we dispose of the shape
  670.     
  671.     // ----- Step 6: Embed it -----
  672.     FW_TRY
  673.     {
  674.         if (embeddedPart != NULL)
  675.         {
  676.             proxyShape->EmbedPart(ev, 
  677.                                     scopeFrame->GetPresentation(ev),
  678.                                     embeddedPart, 
  679.                                     kODFrameObject,        // I want persistent frames
  680.                                     aqFrameShape,
  681.                                     viewType,
  682.                                     NULL,        // no presentation
  683.                                     0,            // group id
  684.                                     FALSE,        // IsOverlaid
  685.                                     FALSE);        // sub frame
  686.         }
  687.         else
  688.         {
  689.             proxyShape->EmbedFrame(ev, 
  690.                                     scopeFrame,
  691.                                     embeddedFrame,
  692.                                     aqFrameShape,
  693.                                     viewType);
  694.         }
  695.     }
  696.     FW_CATCH_BEGIN
  697.     FW_CATCH_EVERYTHING () {
  698.         // cleanup for Step 6
  699.         proxyShape->Release();
  700.         FW_THROW_SAME ();
  701.     }
  702.     FW_CATCH_END
  703.  
  704.     // Step 7: ----- Add the shape to our list -----
  705.     this->AddShape(ev, proxyShape);
  706.     
  707.     return proxyShape;
  708. }
  709.  
  710. //========================================================================================
  711. //    class CDrawContentShapeIterator
  712. //========================================================================================
  713.  
  714. FW_DEFINE_AUTO(CDrawContentShapeIterator)
  715.  
  716. //----------------------------------------------------------------------------------------
  717. //    CDrawContentShapeIterator::CDrawContentShapeIterator
  718. //----------------------------------------------------------------------------------------
  719.  
  720. CDrawContentShapeIterator::CDrawContentShapeIterator(CDrawContent* content) :
  721.     CShapeCollectionIterator(content->fShapeList)
  722. {
  723.     FW_END_CONSTRUCTOR
  724. }
  725.  
  726. //----------------------------------------------------------------------------------------
  727. //    CDrawContentShapeIterator::~CDrawContentShapeIterator
  728. //----------------------------------------------------------------------------------------
  729.  
  730. CDrawContentShapeIterator::~CDrawContentShapeIterator()
  731. {
  732.     FW_START_DESTRUCTOR
  733. }
  734.  
  735. //========================================================================================
  736. //    class CSemanticShapeElementIterator
  737. //========================================================================================
  738.  
  739. FW_DEFINE_AUTO(CSemanticShapeElementIterator)
  740.  
  741. //----------------------------------------------------------------------------------------
  742. //    CSemanticShapeElementIterator::CSemanticShapeElementIterator
  743. //----------------------------------------------------------------------------------------
  744.  
  745. CSemanticShapeElementIterator::CSemanticShapeElementIterator(CDrawContent* content,
  746.                                                             ODDescType desiredClass) :
  747.     fImplementation(content->fShapeList),
  748.     fDesiredClass(desiredClass)
  749. {
  750.     FW_END_CONSTRUCTOR
  751. }
  752.  
  753. //----------------------------------------------------------------------------------------
  754. //    CSemanticShapeElementIterator::~CSemanticShapeElementIterator
  755. //----------------------------------------------------------------------------------------
  756.  
  757. CSemanticShapeElementIterator::~CSemanticShapeElementIterator()
  758. {
  759.     FW_START_DESTRUCTOR
  760. }
  761.  
  762. //----------------------------------------------------------------------------------------
  763. //    CSemanticShapeElementIterator::First
  764. //----------------------------------------------------------------------------------------
  765.  
  766. FW_MScriptable* CSemanticShapeElementIterator::First()
  767. {
  768.     FW_MScriptable* element = fImplementation.First();
  769.     while (element && !IsDesiredClass(element))
  770.         element = Next();
  771.     
  772.     return element;
  773. }
  774.  
  775. //----------------------------------------------------------------------------------------
  776. //    CSemanticShapeElementIterator::Next
  777. //----------------------------------------------------------------------------------------
  778.  
  779. FW_MScriptable* CSemanticShapeElementIterator::Next()
  780. {
  781.     FW_MScriptable* element = fImplementation.Next();
  782.     while (element && !IsDesiredClass(element))
  783.         element = fImplementation.Next();
  784.     
  785.     return element;
  786. }
  787.  
  788. //----------------------------------------------------------------------------------------
  789. //    CSemanticShapeElementIterator::IsDesiredClass
  790. //----------------------------------------------------------------------------------------
  791.  
  792. FW_Boolean CSemanticShapeElementIterator::IsDesiredClass(FW_MScriptable* element) const
  793. {
  794.     FW_Boolean result;
  795.     
  796.     switch (fDesiredClass)
  797.     {
  798.         case typeWildCard:
  799.         case kShapeClass:
  800.             result = TRUE;
  801.             break;
  802.         
  803.         case cOval:
  804.         case cLine:
  805.         case cRectangle:
  806.         case cRoundedRectangle:
  807.             result = (fDesiredClass == element->GetObjectClass());
  808.             break;
  809.             
  810.         default:
  811.             result = FALSE;
  812.             break;
  813.     }
  814.     
  815.     return result;
  816. }
  817.